-- ------------------------------------------------------- --
--  Description: vhdl code used to test the behavior of    --
--               the design                                --
--  Specifications: Constants signals are used to specify  --
--                  generic values of the designed filter  --
--  Author: Shih-Fu Liu                                    --
--          Universidad Antonio de Nebrija. Madrid. Spain  --
--  Contact:sliu@nebrija.es                                --
-- ------------------------------------------------------  -- 


LIBRARY ieee;
library WORK;
library STD;
USE ieee.std_logic_1164.all;
use ieee.std_logic_textio.all;
use std.textio.all;
use work.txt_util.all;



entity FFE_tb is
end;

architecture TEST of FFE_tb is 
constant N : integer := 16;
constant AccuBits : integer := 4;
constant CoefficientsBits : integer := 10;
constant DataBits : integer := 8;

component FFE
GENERIC (N 			: IN integer := 16;    	-- delay taps
	 AccuBits		: IN integer := 4;      -- extra bits ofr the sum
         CoefficientsBits 	: IN integer := 10;	-- bits number of coefficients 	
         DataBits		: IN integer := 8); 	-- Rxin data bit width
port (
	   Rx		: in std_logic_vector (DataBits-1 downto 0); 
	   clk, reset 	: in std_logic;
	   dataout 	: out std_logic);
end component;
  

  -- // SIGNAL ASSIGMENT // --
  
  SIGNAL Rx : std_logic_vector ((DataBits-1) downto 0);
  SIGNAL clk : std_logic := '0';
  SIGNAL Rx_from_file : std_logic := '0';
  SIGNAL datain_from_file : std_logic := '0';
  SIGNAL reset : std_logic := '0';
  signal Tx : std_logic;
  signal Tx_from_file : std_logic :='0';
  SIGNAL dataout : std_logic; 
  
  SIGNAL done: std_logic := '0';
  
  signal cycles : real := -9.0;
  signal error_count : real := 0.0;
  signal percentage : real := 0.0;

begin
    -- instantiate the component
    DUT : component FFE
    	     generic map (N, AccuBits, CoefficientsBits, DataBits) -- BitsNumber
	       port map(Rx , clk ,reset, dataout);
 
 
    -- provide stimulus and check the result
    TESTCLK : process
    
    begin
  
         clk <= not clk after 50 ns;
         
         wait for 2 ns;
         clk <= not clk after 50 ns;

    end process;
    
    -- data_from_file signal determines the time when input file --    
    DATAINVALID : process
   
    begin
       datain_from_file <= not datain_from_file after 2 ns;
       wait for 50 ns;
       
      
    end process;
    
    RESETSIGNAL : process
     
     begin
     
      reset <= '1' after 0 ns;
      wait for 48 ns;
      reset <= '0' after 2 ns;
      wait;
     
     end process;
     

    READ_INPUTS: process   
    
        --file vector_file: text;
        
        file Rx_stimulus_file: TEXT open read_mode is "Rx.txt";
        file Tx_stimulus_file: TEXT open read_mode is "Tx.txt";
        
        variable var_Rx: std_logic_vector((DataBits-1) downto 0);
        variable var_Tx: std_logic;

        -- one variable for each input file --
        variable str_Rx: string(DataBits downto 1);
        variable str_Tx: character;
        -- count errors and current file line of input and output file --
        variable err_cnt: integer := 0;
        variable file_line: line;

 
    begin
        --file_open(vector_file,"Rx.txt",READ_MODE);
        wait until rising_edge(datain_from_file);
        while not endfile(Rx_stimulus_file) loop
            -- read datain stimulus --
            readline (Rx_stimulus_file,file_line);
            read (file_line,str_Rx) ;
            -- read dataout matlab results --
            readline (Tx_stimulus_file,file_line);
            read (file_line,str_Tx) ;
	   
            var_Rx := to_std_logic_vector(str_Rx);
            var_Tx := to_std_logic(str_Tx);
            
            --wait for 1 ns;
            --Get input side of vector...
            -- and expected outputs ...
     
             
            Rx <= var_Rx;
            Tx <= var_Tx;
            
            
            
            wait until rising_edge(clk);
            
            cycles <= cycles +1.0;
	    if (cycles > 0.0) then
	      if (Tx /= dataout) then
	        error_count <= error_count +1.0;
	      end if;
	      percentage <= ((error_count*100.0)/(cycles)); 
	    end if;  
        end loop;

        file_close(Rx_stimulus_file);
        file_close(Tx_stimulus_file);
        
        done <= '1';
        --reset <= '1';

        wait;
    end process READ_INPUTS;
    
 end architecture TEST;

